<?php

namespace app\admin\controller\fssy;

use app\common\controller\Backend;
use think\Log;
use think\Request; // 引入 Request 类
use think\Db;
use app\common\MyLibrary\Utils; // 引入工具类 application\admin\command\MyLibrary\Utils.php
use PhpOffice\PhpSpreadsheet\Spreadsheet;  //导出表使用
use PhpOffice\PhpSpreadsheet\Cell\Coordinate; //导入表使用
use PhpOffice\PhpSpreadsheet\Worksheet\PageSetup;
use PhpOffice\PhpSpreadsheet\Style\Alignment;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx; // 引入 Xlsx 类
use think\exception\HttpException; // 引入 HttpException 类

/**
 * 护士基本统计管理
 *
 * @icon fa fa-circle-o
 */
class Nursecount extends Backend
{

    /**
     * Nursecount模型对象
     * @var \app\admin\model\fssy\Nursecount
     */
    protected $model = null;

    /**
     * 无需鉴权的方法,但需要登录
     * @var array
     */
    protected $noNeedRight = ['getNurseAllCountData'];

    public function _initialize()
    {
        parent::_initialize();
        $this->model = new \app\admin\model\fssy\Nursecount;
    }

    public function index()
    {
        $this->model = new \app\admin\model\dicts\Department;

        // 获取 id=0 的 department 值
        $departmentList = $this->model->field('department')->select();
        array_unshift($departmentList, ['department' => '全部科室']);
        // 将默认值传递给视图
        $this->assign('departmentList', $departmentList);

        // 获取数据库总更新时间的最大值和最小值
        $this->model = new \app\admin\model\fssy\Nurseinfo();
        // 获取最小的 updatetime 数据
        $min_updatetime_data = $this->model->order('updatetime', 'asc')->limit(1)->find();
        // 获取最大的 updatetime 数据
        $max_updatetime_data = $this->model->order('updatetime', 'desc')->limit(1)->find();
        // 时间戳转换成时间 返回2022-05-10 12:51:18格式
        $min_updatetime = date('Y-m-d H:i:s', $min_updatetime_data['updatetime']);
        // 时间戳转换成时间 返回2024-12-07 16:01:29格式
        $max_updatetime = date('Y-m-d H:i:s', $max_updatetime_data['updatetime']);
        // 转换成 年 季度 "2024年 四季度"
        $min_year_quarter = Utils::getQuarterInfo($min_updatetime);
        $max_year_quarter = Utils::getQuarterInfo($max_updatetime);
        $quarterList = Utils::getQuartersBetween($min_year_quarter, $max_year_quarter);
        array_unshift($quarterList, ['quarter' => '']);
        $this->assign('quarterList', $quarterList);

        return $this->fetch();
    }

    // ajax 请求响应函数
    public function getNurseAllCountData(Request $request)
    {
        if ($this->request->isPost()) {
            $department = $request->post('department');
            $quarter_select = $request->post('quarter_select'); // "2023年 二季度"

            // 根据季度信息字符串返回季度的开始和结束日期 2023年 一季度  => ["start_time" => "2023-01-01", "start_time" => "2023-03-31"]
            $CheckedRangeArr = Utils::getQuarterDateRange($quarter_select);
            $Checked_start_date = $CheckedRangeArr['start_time'];  // 2023-01-01
            $Checked_end_date = $CheckedRangeArr['end_time'];      // 2023-03-31

            // 返回上一个季度
            $PriviousQuarter = Utils::getPreviousQuarter($quarter_select); // "2022年 四季度"
            $PriviousRangeArr = Utils::getQuarterDateRange($PriviousQuarter); //  start_time: =>"2022-10-01",   end_time:=> "2022-12-31"
            $Privious_start_date = $PriviousRangeArr['start_time'];  // 2022-10-01
            $Privious_end_date = $PriviousRangeArr['end_time'];      // 2022-12-31

            // 查询nuserinfo表，季报 职称人数、学历人数、年资人数数据
            $CheckedData = $this->getNurseQuarterCountData($department, $Checked_start_date, $Checked_end_date);
            $PriviousData = $this->getNurseQuarterCountData($department, $Privious_start_date, $Privious_end_date);

            // 检查并提取 CheckedData 中的数据
            if (!empty($CheckedData['jobTitleQuarterArr']) && !empty($CheckedData['educationBakQuarterArr']) && !empty($CheckedData['yearPayQuarterArr'])) {
                $CheckedData['jobTitleQuarterArr'] = $CheckedData['jobTitleQuarterArr'][0];
                $CheckedData['educationBakQuarterArr'] = $CheckedData['educationBakQuarterArr'][0];
                $CheckedData['yearPayQuarterArr'] = $CheckedData['yearPayQuarterArr'][0];
            }
            // 检查并提取 PriviousData 中的数据
            if (!empty($PriviousData['jobTitleQuarterArr']) && !empty($PriviousData['educationBakQuarterArr']) && !empty($PriviousData['yearPayQuarterArr'])) {
                $PriviousData['jobTitleQuarterArr'] = $PriviousData['jobTitleQuarterArr'][0];
                $PriviousData['educationBakQuarterArr'] = $PriviousData['educationBakQuarterArr'][0];
                $PriviousData['yearPayQuarterArr'] = $PriviousData['yearPayQuarterArr'][0];
            }

            $data = [
                'department' => $department,
                'CheckedData' => $CheckedData,
                'PriviousData' => $PriviousData,
            ];
            // Log::record('$resultData = ' . json_encode($CheckedData));
            return json(['code' => 1, 'msg' => 'OK', 'data' => $data]);
        }
    }

    // 查询nuserinfo表，季报 职称人数、学历人数、年资人数数据
    /**
     * 根据科室名称或全部科室 查询 科室id、职称、学历、年资人数
     *
     *
     * @param [type] $department
     * @param [type] $start_date
     * @param [type] $end_date
     * @return void 返回数组
     */
    public function getNurseQuarterCountData($department, $start_date, $end_date)
    {
        $this->model = new \app\admin\model\fssy\Nurseinfo;

        // 根据科室名称或全部科室 查询 科室id
        if ($department == '全部科室') {
            $departmentID = "all";  // 全部科室
        } else {
            // 查询数据库, 获取科室id
            $this->model = new \app\admin\model\dicts\Department;
            $departmentInfo = $this->model->where('department', $department)->find();
            $departmentID = $departmentInfo['id'];  // 科室id
            $this->model = new \app\admin\model\fssy\Nurseinfo;
        }

        $min_updatetime = $start_date;  // 2023-01-01
        $max_updatetime = $end_date;    // 2023-03-31

        // 最小 取前4位字符 年 = 2022
        $min_updatetime_year = substr($min_updatetime, 0, 4);
        // 最小 取前5位和6位字符 月 = 05
        $min_updatetime_month = substr($min_updatetime, 5, 2);
        // 最大 取前4位字符 2024
        $max_updatetime_year = substr($max_updatetime, 0, 4);
        // 最大 取前5位和6位字符 月 = 12
        $max_updatetime_month = substr($max_updatetime, 5, 2);

        // 0:        // "2024-01-01 ~ 2024-03-31 一季度"
        // @@@  $max_updatetime_month = 2022; $min_updatetime_month = 05; $max_updatetime_year = 2024; $max_updatetime_month = 12;
        $quarterArr = Utils::generateQuarterDates($min_updatetime_year, $min_updatetime_month, $max_updatetime_year, $max_updatetime_month);

        /**
         *  [0:"2024-01-01 00:00:00~2024-03-31 23:59:59"]
         */
        $dateTimeArr = Utils::convertQuarterDates($quarterArr);

        /***
         * [{ "start": 1704038400, "end": 1711900799 },]
         */
        $dateStampsArr = Utils::dateTimeArrToTimestamps($dateTimeArr);
        // Log::record('$dateStampsArr = ' . json_encode($dateStampsArr));

        // 查询数据 - 聘任职称
        $this->model = new \app\admin\model\dicts\Jobtitle;
        $jobTitle = $this->model->field("jobtitle")->select();
        $jobTitleArr = json_decode(json_encode($jobTitle), true); // 将查询结果转换为数组
        // json_encode 是 PHP 中的一个内置函数，用于将一个值转换为 JSON 格式字符串
        //    [ { "jobtitle": "护士" },
        //     { "jobtitle": "护师" },
        //     { "jobtitle": "主管护师" },
        //     { "jobtitle": "副主任护师" },
        //     { "jobtitle": "主任护师" }]
        // 
        // $jobTitleArr = Array
        // (   [0] => Array  (            [jobtitle] => 护士       )
        //     [1] => Array  (            [jobtitle] => 护师       )
        //     [2] => Array  (            [jobtitle] => 主管护师    )
        //     [3] => Array  (            [jobtitle] => 副主任护师  )
        //     [4] => Array  (            [jobtitle] => 主任护师    ))
        // Log::record('$jobTitleArr = ' .  print_r($jobTitleArr, true));

        // 查询数据 - 聘任职称
        $this->model = new \app\admin\model\dicts\Educationbak;
        $educationBak = $this->model->field("educationbak")->select();
        $educationBakArr = json_decode(json_encode($educationBak), true); // 将查询结果转换为数组

        // 查询数据 - 年金
        $this->model = new \app\admin\model\dicts\Yearpay();
        $yearPay = $this->model->field("yearpay")->select();
        $yearPaykArr = json_decode(json_encode($yearPay), true); // 将查询结果转换为数组

        $jobTitleQuarterArr = [];
        $educationBakQuarterArr = [];
        $yearPayQuarterArr = [];

        // 遍历 $dateStampsArr，进行批量查询
        foreach ($dateStampsArr as $index => $item) {
            $this->model = new \app\admin\model\fssy\Nurseinfo;
            // 每次循环时重新初始化统计数组
            // $jobTitleCounts = [
            //     "护士" => 0,
            //     "护师" => 0,
            //     "主管护师" => 0,
            //     "副主任护师" => 0,
            //     "主任护师" => 0
            // ];
            $jobTitleCounts = Utils::arrSetZero($jobTitleArr, "jobtitle");
            $educationBakCounts = Utils::arrSetZero($educationBakArr, "educationbak");
            $yearPayCounts = Utils::arrSetZero($yearPaykArr, "yearpay");
            // Log::record('$yearPayCounts = ', json_encode($yearPayCounts));

            // 查询数据
            $data = $this->model
                ->with(["dictsusejobtitle", "dictseducationbak"])
                ->whereTime('fa_fssy_nurseinfo.updatetime', '>=', $item["start"])
                ->whereTime('fa_fssy_nurseinfo.updatetime', '<=', $item["end"]);
            if ($departmentID !== "all") {
                $data = $data->where("department_id", '=', $departmentID);
            }
            $data = $data->select();
            // Log::record('$data = ' . json_encode($data));

            // 如果有数据，统计职称数量
            foreach ($data as $nurse) {
                $jobTitle = $nurse->dictsusejobtitle->jobtitle; // 假设职称保存在 dictsusejobtitle 的 jobtitle 属性中
                $educationBak = $nurse->dictseducationbak->educationbak; // 假设职称保存在 dictsusejobtitle 的 jobtitle 属性中
                $yearPay = Utils::calcYearsStep($nurse->work_years); // 假设职称保存在 dictsusejobtitle 的 jobtitle 属性中
                if (array_key_exists($jobTitle, $jobTitleCounts)) {
                    $jobTitleCounts[$jobTitle]++;
                }
                if (array_key_exists($educationBak, $educationBakCounts)) {
                    $educationBakCounts[$educationBak]++;
                }
                if (array_key_exists($yearPay, $yearPayCounts)) {
                    $yearPayCounts[$yearPay]++;
                }
            }

            // 记录统计结果
            $jobTitleItemArr = json_decode(json_encode($jobTitleCounts), true);
            // 在数组前面加上时间区间
            $jobTitleItemArr['range_title'] = $quarterArr[$index];
            $jobTitleItemArr['department'] = $department;
            array_push($jobTitleQuarterArr, $jobTitleItemArr);

            $educationBakItemArr = json_decode(json_encode($educationBakCounts), true);
            // 在数组前面加上时间区间
            $educationBakItemArr['range_title'] = $quarterArr[$index];
            $educationBakItemArr['department'] = $department;
            array_push($educationBakQuarterArr, $educationBakItemArr);

            $yearPayItemArr = json_decode(json_encode($yearPayCounts), true);
            // 在数组前面加上时间区间
            $yearPayItemArr['range_title'] = $quarterArr[$index];
            $yearPayItemArr['department'] = $department;
            array_push($yearPayQuarterArr, $yearPayItemArr);
        }
        $data = [
            'jobTitleQuarterArr' => $jobTitleQuarterArr,
            'educationBakQuarterArr' => $educationBakQuarterArr,
            'yearPayQuarterArr' => $yearPayQuarterArr,
        ];
        return $data;
    }

    public function outputExcel(Request $request)
    {
        if ($this->request->isPost()) {
            try {
                $spreadsheet = new Spreadsheet();
                $sheet = $spreadsheet->getActiveSheet();

                // 设置纸张方向为横向
                $sheet->getPageSetup()->setOrientation(PageSetup::ORIENTATION_LANDSCAPE);

                // 设置页边距
                $sheet->getPageMargins()->setTop(1); // 上边距为1英寸
                $sheet->getPageMargins()->setRight(0.75); // 右边距为0.75英寸
                $sheet->getPageMargins()->setBottom(1); // 下边距为1英寸
                $sheet->getPageMargins()->setLeft(0.75); // 左边距为0.75英寸
                $sheet->getPageMargins()->setHeader(0.3); // 页眉边距为0.3英寸
                $sheet->getPageMargins()->setFooter(0.3); // 页脚边距为0.3英寸

                // 设置标题行
                $sheet->setCellValue('A1', '护士基本信息季度统计表');
                // A1:K2 合并标题单元格并居中
                $sheet->mergeCells('A1:K2');
                $sheet->getStyle('A1:K2')->getAlignment()->applyFromArray([
                    'horizontal' => Alignment::HORIZONTAL_CENTER,
                    'vertical' => Alignment::VERTICAL_CENTER,
                ]);

                $sheet->setCellValue('A2', '科室:内一');
                $sheet->setCellValue('A3', '季度: 2023年 二季度');


                // 设置表头行
                $sheet->setCellValue('A4', 'ID');
                $sheet->setCellValue('B4', '项目 - 职称');
                $sheet->setCellValue('C4', '人数');
                $sheet->setCellValue('D4', 'ID');
                $sheet->setCellValue('E4', '项目 - 学历');
                $sheet->setCellValue('F4', '人数');
                $sheet->setCellValue('G4', 'ID');
                $sheet->setCellValue('H4', '项目 - 年资');
                $sheet->setCellValue('I4', '人数');

                // 设置数据行
                $data = [
                    [1, '2023-01-01~2023-03-31 一季度 - 护士', 1, 1, '2023-01-01~2023-03-31 一季度 - 中专', 2, 1, '2023-01-01~2023-03-31 一季度 - <1年资', 1],
                    [2, '2023-04-01~2023-06-30 二季度 - 护士', 2, 2, '2023-01-01~2023-03-31 一季度 - 中专', 2, 2, '2023-01-01~2023-03-31 一季度 - <1年资', 2],
                    [3, '2023-01-01~2023-03-31 一季度 - 护师', 3, 3, '2023-01-01~2023-03-31 一季度 - 中专', 2, 3, '2023-01-01~2023-03-31 一季度 - <1年资', 3],
                    [4, '2023-04-01~2023-06-30 二季度 - 护师', 3, 4, '2023-01-01~2023-03-31 一季度 - 中专', 2, 4, '2023-01-01~2023-03-31 一季度 - <1年资', 4],
                    [5, '2023-04-01~2023-06-30 二季度 - 护师', 3, 5, '2023-01-01~2023-03-31 一季度 - 中专', 2, 5, '2023-01-01~2023-03-31 一季度 - <1年资', 5],
                    [6, '2023-04-01~2023-06-30 二季度 - 护师', 3, 6, '2023-01-01~2023-03-31 一季度 - 中专', 2, 6, '2023-01-01~2023-03-31 一季度 - <1年资', 6],
                    [7, '2023-04-01~2023-06-30 二季度 - 护师', 3, 7, '2023-01-01~2023-03-31 一季度 - 中专', 2, 7, '2023-01-01~2023-03-31 一季度 - <1年资', 7],
                    [8, '2023-04-01~2023-06-30 二季度 - 护师', 3, 8, '2023-01-01~2023-03-31 一季度 - 中专', 2, 8, '2023-01-01~2023-03-31 一季度 - 10≥y<20年', 8],
                    [9, '2023-04-01~2023-06-30 二季度 - 护师', 3, 9, '2023-01-01~2023-03-31 一季度 - 中专', 2, 9, '2023-01-01~2023-03-31 一季度 - 10≥y<20年', 9],
                    [10, '2023-04-01~2023-06-30 二季度 - 护师', 3, 10, '2023-01-01~2023-03-31 一季度 - 中专', 2, 10, '2023-01-01~2023-03-31 一季度 - 10≥y<20年', 10],
                    [11, '2023-04-01~2023-06-30 二季度 - 护师', 3, 11, '2023-01-01~2023-03-31 一季度 - 中专', 2, 11, '2023-01-01~2023-03-31 一季度 - 10≥y<20年', 11],
                    [12, '2023-04-01~2023-06-30 二季度-各职称总人数', 3, 12, '2023-04-01~2023-06-30 二季度-各学历总人数', 2, 12, '2023-04-01~2023-06-30 二季度-各年资总人数', 11]
                ];

                // 将数据填充到表格中
                $row = 5; // 从第5行开始填充数据
                foreach ($data as $row_data) {
                    $sheet->fromArray($row_data, null, 'A' . $row);
                    $row++;
                }

                // 设置整个工作表的列居中
                $sheet->getDefaultRowDimension()->setRowHeight(20);
                $sheet->getDefaultColumnDimension()->setWidth(20);
                $sheet->getStyle($sheet->calculateWorksheetDimension())->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);

                // 创建 writer 对象来保存文件
                $writer = new Xlsx($spreadsheet);

                // 设置响应头
                header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
                header('Content-Disposition: attachment;filename="考生数据.xlsx"');
                header('Cache-Control: max-age=0');

                // 输出文件到浏览器
                ob_clean(); // 清除输出缓冲区
                flush();    // 刷新输出缓冲区
                $writer->save('php://output');
                exit;
            } catch (\Exception $e) {
                // 捕获异常并返回错误信息
                return json(['code' => 0, 'msg' => '导出失败: ' . $e->getMessage()]);
            }
        } else {
            // 如果不是 POST 请求，返回错误信息
            return json(['code' => 0, 'msg' => '请求方法错误']);
        }
    }

    public function outputExce_ok(Request $request)
    {
        if ($this->request->isPost()) {
            try {
                $spreadsheet = new Spreadsheet();
                $sheet = $spreadsheet->getActiveSheet();

                // 设置表头
                $sheet->setCellValue('A1', '考生ID');
                $sheet->setCellValue('B1', '考生姓名');

                // 改变此处设置的长度数值
                $sheet->getColumnDimension('A')->setWidth(15);
                $sheet->getColumnDimension('B')->setWidth(15);

                // 设置列水平居中
                $sheet->getStyle('A')->getAlignment()
                    ->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
                $sheet->getStyle('B')->getAlignment()
                    ->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);

                // 插入示例数据
                $exampleData = [
                    ['考生ID' => '001', '考生姓名' => '张三'],
                    ['考生ID' => '002', '考生姓名' => '李四'],
                ];

                // 输出表格
                $row = 2; // 数据从第二行开始
                foreach ($exampleData as $data) {
                    $sheet->setCellValue('A' . $row, $data['考生ID']);
                    $sheet->setCellValue('B' . $row, $data['考生姓名']);
                    $row++;
                }

                // 设置整个工作表的列居中
                $sheet->getDefaultRowDimension()->setRowHeight(20);
                $sheet->getDefaultColumnDimension()->setWidth(20);
                $sheet->getStyle($sheet->calculateWorksheetDimension())->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);

                // 创建 writer 对象来保存文件
                $writer = new Xlsx($spreadsheet);

                // 设置响应头
                header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
                header('Content-Disposition: attachment;filename="考生数据.xlsx"');
                header('Cache-Control: max-age=0');

                // 输出文件到浏览器
                ob_clean(); // 清除输出缓冲区
                flush();    // 刷新输出缓冲区
                $writer->save('php://output');
                exit;
            } catch (\Exception $e) {
                // 捕获异常并返回错误信息
                return json(['code' => 0, 'msg' => '导出失败: ' . $e->getMessage()]);
            }
        } else {
            // 如果不是 POST 请求，返回错误信息
            return json(['code' => 0, 'msg' => '请求方法错误']);
        }
    }

    public function outputExcel1()
    {
        try {
            // 创建一个新的电子表格对象
            $spreadsheet = new Spreadsheet();
            $sheet = $spreadsheet->getActiveSheet();

            // 设置表头数据
            $headers = [
                'A1' => '考生ID',
                'B1' => '考生姓名',
                'C1' => '考生性别',
                'D1' => '备注'
            ];

            foreach ($headers as $cell => $text) {
                $sheet->setCellValue($cell, $text);
            }

            // 设置样式（加粗居中）
            $styleArray = [
                'font' => ['bold' => true],
                'alignment' => ['horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER]
            ];
            $sheet->getStyle('A1:D1')->applyFromArray($styleArray);

            // 自动调整列宽
            foreach (range('A', 'D') as $col) {
                $sheet->getColumnDimension($col)->setAutoSize(true);
            }

            // 模拟填充几行数据（可替换为实际数据查询）
            $data = [
                [1, '张三', '男', '优秀'],
                [2, '李四', '女', '良好'],
                [3, '王五', '男', '合格']
            ];

            $row = 2; // 从第二行开始填充数据
            foreach ($data as $item) {
                $sheet->fromArray($item, NULL, 'A' . $row++);
            }

            // 输出文件到浏览器
            header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
            header('Content-Disposition: attachment;filename="export.xlsx"');
            header('Cache-Control: max-age=0');

            $writer = new Xlsx($spreadsheet);
            $writer->save('php://output');
            exit;
        } catch (\Exception $e) {
            throw new HttpException(500, '导出失败: ' . $e->getMessage());
        }
    }


    /**
     * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
     * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
     * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
     */
}
